/*
 * @Author: 缄默
 * @Date: 2021-12-12 15:17:19
 * @LastEditors: 缄默
 * @LastEditTime: 2021-12-30 16:15:24
 */

//中介者模式

#include <iostream>
#include <vector>
#include <list>
#include <string>

using namespace std;

class Colleague;

class Mediator {
public:
    virtual void Register(Colleague* col) = 0;

    virtual ~Mediator() { }

    virtual void printList() = 0;

public:
    list<Colleague*> _list;
};

class Colleague {
public:
    Colleague(string tel) : _tel(tel) { }

    virtual void setMedium(Mediator* mediator) = 0;

    virtual void receive(Colleague* colleague) = 0;

    virtual void send(Colleague* colleague) = 0;

    virtual void send() = 0;

    virtual ~Colleague() { }

    string& getTel() {
        return _tel;
    }

protected:
    Mediator* _mediator;
    string _tel;
};

class ConcreteColleague : public Colleague {
public:
    ConcreteColleague(string& tel) : Colleague(tel) { }
    
    void setMedium(Mediator* mediator) { 
        _mediator = mediator;
    }

    void receive(Colleague* colleague) { 
        cout << colleague->getTel() << endl;
    }

    void send(Colleague* colleague) { 
        if (colleague == this) return;
        colleague->receive(this);
    }

    void send() {
        for (auto x : _mediator->_list) {
            if (x != this) {
                x->receive(this);
            }
        }
    }
};

class ConcreteMediator : public Mediator { 
public:
    void Register(Colleague* col) {
        _list.push_back(col);
    }

    void printList() {
        for (auto x : _list) {
            cout << x->getTel() << endl;
        }
    }
};


int main() {
    
    string s1 = "123";
    Colleague* col1 = new ConcreteColleague(s1);
    s1 = "456";
    Colleague* col2 = new ConcreteColleague(s1);
    s1 = "789";
    Colleague* col3 = new ConcreteColleague(s1);

    Mediator* med = new ConcreteMediator();
    med->Register(col1);
    med->Register(col2);
    med->Register(col3);

    med->printList();

    col1->setMedium(med);
    col1->send();

    
    delete col1;
    delete col2;
    delete col3;

    delete med;
    
    return 0;
}